﻿using System;

namespace POP.Pop3
{
	// Utility class that simplifies the usage of <see cref="IDisposable"/>
	public abstract class Disposable : IDisposable
	{
		// Returns <see langword="true"/> if this instance has been disposed of, <see langword="false"/> otherwise
		protected bool IsDisposed { get; private set; }

		// Releases unmanaged resources and performs other cleanup operations before the
		~Disposable()
		{
			Dispose(false);
		}

		// Releases unmanaged and - optionally - managed resources
		public void Dispose()
		{
			if (!IsDisposed)
			{
				try
				{
					Dispose(true);
				} finally
				{
					IsDisposed = true;
					GC.SuppressFinalize(this);
				}
			}
		}

		// Releases unmanaged and - optionally - managed resources. Remember to call this method from your derived classes.
		protected virtual void Dispose(bool disposing)
		{
		}

		// Used to assert that the object has not been disposed
		// The method is to be used by the subclasses in order to provide a simple method for checking the 
		// disposal state of the object.
		protected void AssertDisposed()
		{
			if (IsDisposed)
			{
				string typeName = GetType().FullName;
				throw new ObjectDisposedException(typeName, String.Format(System.Globalization.CultureInfo.InvariantCulture, "Cannot access a disposed {0}.", typeName));
			}
		}
	}
}